Skip to content

fix(nix): apply logos-nix's native overlays in mkPkgsWith - #233

Merged
dlipicar merged 1 commit into
masterfrom
feat/wire-logos-nix-native-overlays
Sep 8, 2026
Merged

fix(nix): apply logos-nix's native overlays in mkPkgsWith#233
dlipicar merged 1 commit into
masterfrom
feat/wire-logos-nix-native-overlays

Conversation

@dlipicar

@dlipicar dlipicar commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

The consumer line for logos-co/logos-nix#9, #10 and #11. Supersedes #220 — see the
comment there.

The problem

mkPkgsWith (lib/common.nix) was a bare
import nixpkgs { inherit system; overlays = extraOverlays; }, so every module's
package set missed logos-nix's crates.io fixes. crates.io's /api/v1/crates/*/download
returns 403 to any User-Agent starting curl/ — exactly what nixpkgs' fetchurl
sends — so a Rust module 403s on every crate the org cache misses.

mkLogosModule vendors with cargoLock (lib/mkLogosModule.nix:586), i.e. through
importCargoLock, not fetchCargoVendor. #220 wires only the UA overlay, which
fixes the other fetcher; it is not the one module crates go through.

The change

Take logos-nix's lib.nativeOverlays list rather than naming entries. Naming them is
exactly how the importCargoLock fix reached master applying to nothing, and a third
overlay would repeat it. The logos-nix pin moves to master for that export — nixpkgs
stays at e9f00bd8 and the lock keeps all 756 nodes, so nothing else in the closure
shifts.

An old logos-nix throws rather than silently applying nothing:

logos-module-builder: the pinned logos-nix predates lib.nativeOverlays, so Rust
modules would vendor crates from an endpoint crates.io 403s. Bump the logos-nix
input past logos-co/logos-nix#11.

#220's lib.optional (logos-nix ? lib.overlays.X) shape degrades to a no-op on a stale
pin and re-opens the 403 with no diagnostic — the exact failure mode this chain exists
to close. logos-nix == null still yields [ ] and is unaffected.

Measured

On checks.aarch64-darwin.rust-native-dep, reading urls off the crate FODs in the
realised closure (not an eval-level guess):

crate fetches endpoint
before 15 all https://crates.io/api/v1/crates
after 12 moved to https://static.crates.io/crates

The UA overlay arrives too — fetch-cargo-vendor-util-ua appears in the closure.

Merge order — this needs a coupled workspace bump

The new throw is reachable by the primary consumer. logos-workspace/flake.nix:25 pins
logos-nix at 6e0f4a71 and 32 inputs.logos-nix.follows lines force every repo,
including this builder, onto that pin. Measured in the workspace:

nix eval .#logos-capability-module.drvPath --override-input logos-module-builder path:<this branch>
  -> logos-module-builder: the pinned logos-nix predates lib.nativeOverlays ...

That is a C++ module, and .#logos-liblogos throws the same way — the workspace's
allPkgs fold is strict, so a stale pin surfaces as a crates.io error on repos that
have nothing to do with Rust.

No immediate breakage on merge: the workspace currently pins this builder at e234a4c6,
before this change. But whoever next bumps logos-module-builder past this commit must
bump logos-nix past logos-co/logos-nix#11 in the same change
, and anyone running
ws build --auto-local against a local checkout of this branch hits it today. The
alternative — degrading to [] on a stale pin — is the fail-open shape that let this bug
live for weeks, so the throw stays and the message names the fix.

This is necessary but NOT sufficient

Two further holes, neither reachable from here.

1. logos-rust-sdk. The other 11 crate fetches in this subject's closure belong to
logos-lidl-gen, built by logos-rust-sdk from its own bare import nixpkgs. It needs
two edits, not one — flake.nix:69 for the package outputs and flake.nix:196,
which the sdk-unit-tests check resolves against; fixing only :69 leaves that check
vendoring through the 403 endpoint. Currently latent rather than fatal: all 11 are
substitutable from cache.nixos.org today, so a green run proves the cache is warm, not
that the fetch works.

2. A third fetcher neither overlay covers. fetchCrate still points at the API
endpoint — logos-co/logos-nix#9 left it there deliberately, on the grounds that nothing
fetched through it. That is not true of a module closure: rav1e and cargo-c arrive as
fetchCrate source tarballs via qtdeclarative -> qtsvg -> jasper -> libheif, and
https://crates.io/api/v1/crates/rav1e/0.8.1/download returns 403 today to the
User-Agent nixpkgs' fetchurl sends. Same latency caveat: cached today, fatal on a cold
store.

So: do not read a green run here as "Rust module builds are fixed".

Blast radius

The only derivations this change touches are fixed-output ones — the crate tarballs
and the *-vendor-staging FODs — plus one new fetch-cargo-vendor-util-ua helper.
46 of 1284 derivations differ and every root is a FOD, so hashDerivationModulo
absorbs them and none propagates downstream.

Module output paths do move, but for an unrelated, pre-existing reason:
LOGOS_MODULE_BUILDER_ROOT embeds the builder's own source path, so any commit here
moves every module. Two independent proofs: appending a single no-op comment to
lib/common.nix on master moves them exactly the same way, and an isolation run holding
the builder source fixed while neutering the overlays (--override-input logos-module-builder/logos-nix at a copy with nativeOverlays = [ ]) reproduces the
identical module and .lgx outPaths. The overlays move zero outputs.

Also verified end to end, substituters disabled: the pre-change crate derivation dies on
curl (22) ... 403, the post-change one builds — and both land on the same store path.
The custom-toolchain path works too: logos-chat-module (nix.rust.toolchain 1.95.0, 11
git deps) moves all 561 of its crates to the CDN with no throw.

🤖 Generated with Claude Code

mkPkgsWith was a bare `import nixpkgs { overlays = extraOverlays; }`, so every
module's package set missed logos-nix's crates.io fixes. crates.io returns 403
to any User-Agent starting "curl/" -- exactly what nixpkgs' fetchurl sends --
so a Rust module 403s on any crate the org cache misses.

mkLogosModule vendors with `cargoLock`, i.e. through importCargoLock, NOT
fetchCargoVendor. #220 wires only the UA overlay, which covers the other
fetcher; it is not the one module crates go through.

Take logos-nix's `lib.nativeOverlays` list rather than naming entries. Naming
them is how the importCargoLock fix reached master applying to nothing, and a
third overlay would repeat it. The pinned logos-nix moves to master for the
export (nixpkgs stays at e9f00bd8 and the lock keeps all 756 nodes, so nothing
else in the closure shifts).

An old logos-nix throws rather than silently applying nothing. #220's
`lib.optional (logos-nix ? ...)` shape degrades to a no-op on a stale pin and
re-opens the 403 with no diagnostic, which is the failure mode this whole chain
exists to close. `logos-nix == null` still yields [ ] and is unaffected.

Measured on checks.aarch64-darwin.rust-native-dep, reading `urls` off the crate
FODs in the realised closure:

  before   15 crate fetches, all on https://crates.io/api/v1/crates
  after    12 moved to https://static.crates.io/crates

NOT SUFFICIENT ON ITS OWN. The other 11 belong to logos-lidl-gen, built by
logos-rust-sdk, which does its own bare `import nixpkgs` (flake.nix:69 and
:196) and so is untouched by this. A module build still reaches the 403
endpoint for those until logos-rust-sdk gets the same wiring -- and that is the
repo whose doc-tests run started this.

Blast radius: the only derivations this change touches are fixed-output ones
(the crate tarballs and the *-vendor-staging FODs) plus one new
fetch-cargo-vendor-util-ua helper -- 46 of 1284, every root a FOD, so
hashDerivationModulo absorbs them and none propagates. Module output paths do
move, for the unrelated pre-existing reason that LOGOS_MODULE_BUILDER_ROOT
embeds the builder's source path: appending a single no-op comment to
lib/common.nix moves them exactly the same way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

📊 Doc-test reports

The four ways to wrap a C library plus the two cross-language composition tours — each scaffolded into real modules, built against this commit, loaded in logoscore, and driven — rendered alongside the commands actually run and their output (updated each run, commit 0d53a68):

Pages can take a minute to update after the run finishes.

@dlipicar
dlipicar merged commit 29e48e8 into master Sep 8, 2026
4 checks passed
dlipicar added a commit to logos-co/logos-rust-sdk that referenced this pull request Sep 8, 2026
This flake built Rust twice through a bare `import nixpkgs`, so neither set
carried logos-nix's crates.io fixes. crates.io returns 403 to any User-Agent
starting "curl/" -- exactly what nixpkgs' fetchurl sends -- so every crate the
org cache misses is unfetchable.

Two sites, and both mattered: :69 fed packages.lidl-gen and the devShells, :196
fed the checks, including sdk-unit-tests. Fixing only one leaves the other
vendoring from the dead endpoint, so they are collapsed into a single mkPkgs
rather than given the same overlay list twice -- two independent
`import nixpkgs` calls drifting is the shape of this bug.

Measured on aarch64-darwin, reading `urls` off the crate FODs in the realised
closure:

                      before              after
  lidl-gen            11 crates on API    11 on static.crates.io
  sdk-unit-tests      11 crates on API    11 on static.crates.io

Takes logos-nix's `lib.nativeOverlays` list rather than naming entries; naming
them is how the importCargoLock fix reached master applying to nothing. No
custom guard for a too-old logos-nix, unlike logos-module-builder: there the
throw surfaces far from its cause (a stale pin shows up while evaluating a C++
repo), here a bare `attribute 'nativeOverlays' missing` points straight at this
file. The pin is unpinned and re-locks to master; nixpkgs stays at e9f00bd8.

lidl-gen and sdk-unit-tests outPaths move, but not because of the overlays:
both derivations take the flake source as `src`, so any edit to flake.nix moves
them. Appending a single no-op comment to flake.nix on master moves lidl-gen
exactly the same way (gh2jgb1f -> n203wr42, against the wired 9i9sm3kb).

All three checks evaluate. Note this closes the module-side hole flagged in
logos-co/logos-module-builder#233 -- lidl-gen is in every Rust module's graph --
but a third fetcher is still unfixed: `fetchCrate` source tarballs (rav1e,
cargo-c, reached via Qt) remain on the 403 endpoint. They are not in this
repo's closure; they are in a module's.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
dlipicar added a commit that referenced this pull request Sep 8, 2026
…nix (#234)

* chore(deps): relock logos-nix and logos-rust-sdk for the crates.io fixes

Lock-only. #233 wired mkPkgsWith to logos-nix's `lib.nativeOverlays`, and both
pins have since gone stale relative to the fixes that list carries.

  logos-nix       782d8690 -> 30285b1  (adds the fetchCrate overlay, #12)
  logos-rust-sdk  6462fd15 -> 102f867  (applies the overlays to both of its own
                                        package sets, logos-rust-sdk#56)

No source change was needed for either: lib/common.nix takes the LIST, so the
third overlay wires itself in. Verified by evaluation -- lib.nativeOverlays goes
2 -> 3 and the tree is byte-identical apart from flake.lock.

Measured on checks.aarch64-darwin.rust-native-dep, counting fetchers by `urls`
and marking an API fetcher "uncovered" when no CDN fetcher in the same closure
shares its outputHash:

  before   API=13  CDN=12  uncovered=5
  after    API= 2  CDN=17  uncovered=0

The rust-sdk half is the bigger one: it clears memchr 2.8.0, serde_json 1.0.149
and syn 2.0.117, which reach the closure through logos-lidl-gen's vendor dir and
had no CDN twin at all. The logos-nix half clears rav1e and cargo-c inside this
builder's own package set.

The 2 survivors are twinned rav1e/cargo-c coming from logos-qt-sdk, which builds
its own un-overlaid Qt; logos-co/logos-qt-sdk#54 removes them. Twinned is
mitigation, not safety -- two derivations sharing an output path are two build
goals, and on a cold cache whichever runs first wins.

nixpkgs is untouched (e9f00bd8 either side) and the lock keeps all 756 nodes.
Module output paths move, as they do for any change here, because flake.lock is
part of the source LOGOS_MODULE_BUILDER_ROOT points at.

Also refreshes lib/common.nix's "the two crates.io 403 fixes", stale at three.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(nix): make the SDK inputs follow our logos-nix, and relock qt-sdk

The relock alone left two crates.io/api fetchers in a module closure. I said
logos-co/logos-qt-sdk#54 would remove them; measured, it does not.

Tracing them: the closure carried TWO qtremoteobjects derivations sharing one
output path -- an overlaid one feeding logos-qt-sdk-lib and the module, and an
un-overlaid one feeding logos-cpp-sdk-generator, logos-protocol-lib and
logos-qt-host. Those three resolve their OWN logos-nix, and all three sat at
6e0f4a71, which carries no overlays at all. #54 fixed logos-qt-sdk's package
set, not theirs.

They already route packages through logos-nix.lib.forAllTargets, so they need
no code change -- only our logos-nix instead of their stale one. Three
`inputs.logos-nix.follows` lines, matching how this flake already pins
logos-protocol and logos-plugin-qt across the same inputs.

  checks.aarch64-darwin.rust-native-dep, fetchers counted by `urls`:
    master                          API=13  CDN=12  uncovered=5
    + logos-nix and rust-sdk relock API= 2  CDN=17  uncovered=0
    + logos-qt-sdk relock           API= 2  CDN=17  uncovered=0
    + these three follows           API= 0  CDN=17  uncovered=0

Reaching API=0 matters beyond tidiness: an API and a CDN fetcher sharing an
output path are two build goals, and on a cold cache whichever is scheduled
first runs. Twinned was mitigation; this removes the goal.

The qt-sdk relock (5c094543 -> b2ebecc, #54) stays. It is what stops
logos-qt-sdk-lib carrying its own API fetchers, which matters to anyone
building that flake directly even though it did not move this closure.

The follows also dedupe the lock: 756 -> 747 nodes. nixpkgs is untouched at
e9f00bd8 and `nix flake check --no-build --all-systems` exits 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant